package com.example.logisticsingle.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.Map;

/**
 * RestTemplate 远程调用工具类
 *
 */
@Component
public class RestTemplateUtils {
    private static RestTemplate restTemplate;

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        RestTemplateUtils.restTemplate = restTemplate;
    }

    /**
     * GET请求调用
     * @param <T>
     * @param url	请求URL
     * @param clazz	返回对象类型
     * @return	响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, Class<T> clazz) {
        return restTemplate.getForEntity(url, clazz);
    }
    /**
     * GET请求调用
     * @param <T>
     * @param url	请求URL
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, Class<T> clazz, Object... urlParams) {
        return restTemplate.getForEntity(url, clazz, urlParams);
    }
    /**
     * GET请求调用
     * @param <T>
     * @param url	请求URL
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, Class<T> clazz, Map<String, ?> urlParams) {
        return restTemplate.getForEntity(url, clazz, urlParams);
    }
    /**
     * 带请求头的GET请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> clazz, Object... urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return get(url, httpHeaders, clazz, urlParams);
    }
    /**
     * 带请求头的GET请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> clazz, Object... urlParams) {
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        return exchange(url, HttpMethod.GET, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的GET请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> clazz, Map<String, ?> urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return get(url, httpHeaders, clazz, urlParams);
    }
    /**
     * 带请求头的GET请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> clazz, Map<String, ?> urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        return exchange(url, HttpMethod.GET, requestEntity, clazz, urlParams);
    }
    /**
     * POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param clazz	返回对象类型
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, Class<T> clazz) {
        return restTemplate.postForEntity(url, HttpEntity.EMPTY, clazz);
    }
    /**
     * POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> clazz) {
        return restTemplate.postForEntity(url, requestBody, clazz);
    }
    /**
     * POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> clazz, Object... urlParams) {
        return restTemplate.postForEntity(url, requestBody, clazz, urlParams);
    }
    /**
     * POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> clazz, Map<String, ?> urlParams) {
        return restTemplate.postForEntity(url, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody,
                                             Class<T> clazz, Object... urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return post(url, httpHeaders, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody,
                                             Class<T> clazz, Object... urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return post(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody,
                                             Class<T> clazz, Map<String, ?> urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return post(url, httpHeaders, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody,
                                             Class<T> clazz, Map<String, ?> urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return post(url, requestEntity, clazz, urlParams);
    }
    /**
     * 自定义请求头和请求体的POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity,
                                             Class<T> clazz, Object... urlParams) {
        return restTemplate.exchange(url, HttpMethod.POST, requestEntity, clazz, urlParams);
    }
    /**
     * 自定义请求头和请求体的POST请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity,
                                             Class<T> clazz, Map<String, ?> urlParams) {
        return restTemplate.exchange(url, HttpMethod.POST, requestEntity, clazz, urlParams);
    }
    /**
     * PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param clazz	 返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, Class<T> clazz, Object... urlParams) {
        return put(url, HttpEntity.EMPTY, clazz, urlParams);
    }
    /**
     * PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> clazz, Object... urlParams) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return put(url, requestEntity, clazz, urlParams);
    }
    /**
     * PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> clazz, Map<String, ?> urlParams) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return put(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody,
                                            Class<T> clazz, Object... urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return put(url, httpHeaders, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody,
                                            Class<T> clazz, Object... urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return put(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody,
                                            Class<T> clazz, Map<String, ?> urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return put(url, httpHeaders, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody,
                                            Class<T> clazz, Map<String, ?> urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return put(url, requestEntity, clazz, urlParams);
    }
    /**
     * 自定义请求头和请求体的PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity,
                                            Class<T> clazz, Object... urlParams) {
        return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, clazz, urlParams);
    }
    /**
     * 自定义请求头和请求体的PUT请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity,
                                            Class<T> clazz, Map<String, ?> urlParams) {
        return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, clazz, urlParams);
    }
    /**
     * DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Class<T> clazz, Object... urlParams) {
        return delete(url, HttpEntity.EMPTY, clazz, urlParams);
    }
    /**
     * DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Class<T> clazz, Map<String, ?> urlParams) {
        return delete(url, HttpEntity.EMPTY, clazz, urlParams);
    }
    /**
     * DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Object requestBody,
                                               Class<T> clazz, Object... urlParams) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return delete(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers,
                                               Class<T> clazz, Object... urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> clazz, Object... urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
        return delete(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers,
                                               Class<T> clazz, Map<String, ?> urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers,
                                               Class<T> clazz, Map<String, ?> urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
        return delete(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody,
                                               Class<T> clazz, Object... urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody,
                                               Class<T> clazz, Object... urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return delete(url, requestEntity, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody,
                                               Class<T> clazz, Map<String, ?> urlParams) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, requestBody, clazz, urlParams);
    }
    /**
     * 带请求头的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param headers	请求头参数
     * @param requestBody	请求参数体
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody,
                                               Class<T> clazz, Map<String, ?> urlParams) {
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return delete(url, requestEntity, clazz, urlParams);
    }
    /**
     * 自定义请求头和请求体的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity,
                                               Class<T> clazz, Object... urlParams) {
        return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, clazz, urlParams);
    }
    /**
     * 自定义请求头和请求体的DELETE请求调用方式
     * @param <T>
     * @param url	请求URL
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity,
                                               Class<T> clazz, Map<String, ?> urlParams) {
        return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, clazz, urlParams);
    }
    /**
     * 通用调用方式
     * @param <T>
     * @param url	请求URL
     * @param method	请求方法类型
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                                 Class<T> clazz, Object... urlParams) {
        return restTemplate.exchange(url, method, requestEntity, clazz, urlParams);
    }
    /**
     * 通用调用方式
     * @param <T>
     * @param url	请求URL
     * @param method	请求方法类型
     * @param requestEntity	请求头和请求体封装对象
     * @param clazz	返回对象类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                                 Class<T> clazz, Map<String, ?> urlParams) {
        return restTemplate.exchange(url, method, requestEntity, clazz, urlParams);
    }
    /**
     * 返回结果带泛型请求(带请求头）
     * @param <T>
     * @param url
     * @param method
     * @param headerMap
     * @param requestBody
     * @param responseType
     * @return
     */
    public static <T> ResponseEntity<T> exchangeByTypeReference(String url, HttpMethod method, Map<String, String> headerMap,Object requestBody,
                                                                ParameterizedTypeReference<T> responseType){
        HttpHeaders headers = new HttpHeaders();
        headers.setAll(headerMap);
        return exchangeByTypeReference(url, method, headers, requestBody, responseType);
    }

    /**
     * 返回结果带泛型请求(带请求头）
     * @param <T>
     * @param url
     * @param method
     * @param headers
     * @param requestBody
     * @param responseType
     * @return
     */
    public static <T> ResponseEntity<T> exchangeByTypeReference(String url, HttpMethod method, HttpHeaders headers,Object requestBody,
                                                                ParameterizedTypeReference<T> responseType){
        MimeType mimeType = MimeTypeUtils.parseMimeType("application/json");
        MediaType mediaType = new MediaType(mimeType.getType(), mimeType.getSubtype(), Charset.forName("UTF-8"));
        headers.setContentType(mediaType);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return restTemplate.exchange(url, method, requestEntity, responseType);
    }
    /**
     * 返回结果带泛型请求
     * @param <T>
     * @param url	请求URL
     * @param method	请求方法类型
     * @param requestEntity	请求头和请求体封装对象
     * @param responseType	泛型类型
     * @param urlParams	URL中的变量，按顺序依次对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> exchangeByTypeReference(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                                                ParameterizedTypeReference<T> responseType, Object... urlParams) {
        return restTemplate.exchange(url, method, requestEntity, responseType, urlParams);
    }
    /**
     * 返回结果带泛型请求
     * @param <T>
     * @param url	请求URL
     * @param method	请求方法类型
     * @param requestEntity	请求头和请求体封装对象
     * @param responseType	泛型类型
     * @param urlParams	URL中的变量，与Map中的key对应
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> exchangeByTypeReference(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                                                ParameterizedTypeReference<T> responseType,Map<String, ?> urlParams){
        return restTemplate.exchange(url, method, requestEntity, responseType, urlParams);
    }
    /**
     * 返回结果带泛型请求(URL无参数)
     * @param <T>
     * @param url	请求URL
     * @param method	请求方法类型
     * @param requestEntity	请求头和请求体封装对象
     * @param responseType	泛型类型
     * @return	ResponseEntity 响应对象封装类
     */
    public static <T> ResponseEntity<T> exchangeByTypeReference(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                                                ParameterizedTypeReference<T> responseType){
        return restTemplate.exchange(url, method, requestEntity, responseType);
    }

    public static <T> ResponseEntity<T> exchangeByTypeReference(String url, HttpMethod method, Object requestBody,
                                                                ParameterizedTypeReference<T> responseType){
        HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody);
        return restTemplate.exchange(url, method, requestEntity, responseType);
    }
}
